﻿using System.Collections.Generic;
using System.Text;
using AspectIntercept;
using GestorSQL.BusinessEntities;
using GestorSQL.DAO;
using GestorSQL.DAO.InterceptDAO;
using GestorSQL.Utility;
using GestorSQL.DataBase.Interface;
using GestorSQL.BLL.ImplementationsBridge;

namespace GestorSQL.BLL
{
    [Intercept(InterceptAllMethods = true, PreProcesor = typeof(DBTraceProcessor), PostProcesor = typeof(DBTraceProcessor), OmitMethods = new string[] { })]
    public class ConnectionManager : InterceptContext
    {

        #region Variables Privadas
        private IGestorSqlDao dao = new GestorSqlDao();

        #endregion

        #region Metodos Publicos

        /// <summary>
        /// Obtiene la lista de Ambiente por role
        /// <param name="roles">Roles del usuario</param>
        /// </summary>
        /// <returns></returns>
        [InterceptOmit]
        public List<Ambiente> GetEnvironmentList(string[] roles)
        {
            return dao.GetEnvironmentList(roles);
        }

        /// <summary>
        /// Obtiene la lista de Servidores por ambiente
        /// </summary>
        /// <param name="environment">Ambiente</param>
        /// <returns></returns>
        [InterceptOmit]
        public List<string> GetServerListByEnvironment(Ambiente environment)
        {
            return dao.GetServerListByEnvironment(environment);
        }

        /// <summary>
        /// Obtiene la lista de conexiones por servidor y ambiente
        /// </summary>
        /// <param name="environment">Ambiente</param>
        /// <param name="server">Servidor</param>
        /// <returns></returns>
        [InterceptOmit]
        public List<string> GetConnectionListByServerAndEnvironment(Ambiente environment, string server)
        {
            return dao.GetConnectionListByServerAndEnvironment(environment, server);
        }

        /// <summary>
        /// Obtiene la lista de conexiones por core
        /// </summary>
        /// <param name="idCore">Identificador del Core</param>
        /// <returns>Lista de Servidores</returns>
        [InterceptOmit]
        public List<string> GetConnectionListByCore(int idCore)
        {
            return dao.GetConnectionListByCore(idCore);
        }

        /// <summary>
        /// Obtiene la lista de servidores de acuerdo al core
        /// </summary>
        /// <param name="idCore">Identificador del Core</param>
        /// <returns></returns>
        [InterceptOmit]
        public List<string> GetServerListByCore(int idCore)
        {
            return dao.GetServerListByCore(idCore);
        }

        /// <summary>
        /// Obtiene el listado de servidores
        /// </summary>
        /// <returns></returns>
        [InterceptOmit]
        public List<string> GetServerList()
        {
            return dao.GetServerList();
        }

        /// <summary>
        /// Obtiene una conexion por su nombre
        /// </summary>
        /// <param name="connectionName">Nombre de la conexion</param>
        /// <returns></returns>
        [InterceptOmit]
        public Conexion GetConnection(string connectionName)
        {
            return dao.GetConnection(connectionName);
        }

        /// <summary>
        /// Obtiene la cadena de conexion de acuerdo al caso
        /// </summary>
        /// <param name="caso"></param>
        /// <returns></returns>
        [InterceptOmit]
        public string GetConnectionStringByCase(Caso caso)
        {
            Conexion conexion = null;
            StringBuilder connectionString = new StringBuilder();

            if (caso.IsProduction(caso.Historia.Estado_))
                conexion = dao.GetConnection(caso.Conexion1.IdConexion);
            else
                conexion = dao.GetConnection(caso.Conexion.IdConexion);

            Core core = dao.GetCoreById(conexion.Fk_Core);

            connectionString.Append(string.Format(core.ConnectionString,
                conexion.Servidor, conexion.BaseDeDatos,
                conexion.Usuario.Decrypt(),
                conexion.Contrasena.Decrypt()));

            if (!string.IsNullOrEmpty(conexion.Propiedades))
                connectionString.Append(";" + conexion.Propiedades);

            return connectionString.ToString();
        }
            
        /// <summary>
        /// Obtiene la cadena de conexion de una conexion especifica.
        /// </summary>
        /// <param name="caso"></param>
        /// <returns></returns>
        [InterceptOmit]
        public string GetConnectionStringByConnection(Conexion conexion)
        {
            StringBuilder connectionString = new StringBuilder();

            Core core = dao.GetCoreById(conexion.Fk_Core);

            connectionString.Append(string.Format(core.ConnectionString,
                conexion.Servidor, conexion.BaseDeDatos,
                conexion.Usuario.Decrypt(),
                conexion.Contrasena.Decrypt()));

            if (!string.IsNullOrEmpty(conexion.Propiedades))
                connectionString.Append(";" + conexion.Propiedades);


            return connectionString.ToString();
        }

        /// <summary>
        /// Prueba si una conexion a un core dado es valida
        /// </summary>
        /// <param name="conexion">Conexion</param>
        [InterceptOmit]
        public bool TestConnection(Conexion conexion)
        {
            try
            {
                IDataBaseProvider dataManager = ImplementationBridge.GetDataBaseImplementationByCore(conexion.Fk_Core);
                dataManager.ConnectionString = GetConnectionStringByConnection(conexion);
                dataManager.Open();
                dataManager.Close();
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// Obtiene una lista de conexiones existentes
        /// </summary>
        /// <returns>Lista de Conexiones Existentes ordenadas por servidor</returns>
        [InterceptOmit]
        public List<Conexion> GetConnectionsList()
        {

            return dao.GetConnectionList();

        }

        /// <summary>
        /// Guarda una conexion nueva o modifica una existente
        /// </summary>
        /// <param name="connection">Conexion</param>
        /// <returns></returns>
        public Resultado SaveConnection(Conexion connection)
        {
            return dao.SaveConnection(connection);
        }

        /// <summary>
        /// Eliminar una conexion
        /// </summary>
        /// <param name="conexctionName">Nombre de la conexion</param>
        public Resultado RemoveConnection(string connectionName)
        {
            return dao.RemoveConnection(connectionName);
        }

        /// <summary>
        /// Obtiene la lista de Core registrados
        /// </summary>
        /// <returns></returns>
        [InterceptOmit]
        public List<Core> GetCoreList()
        {

            return dao.GetCoreList();
        }

        #endregion
    }
}
